package com.bz.redis.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class RedisCachceUtil {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 获取单个缓存
     * @param key
     * @param clazz
     * @param consumer1
     * @param timeout
     * @param <T>
     * @return
     */
    public <T>T getCache(String key,Class<T> clazz,Consumer1<T> consumer1,Long timeout){
        T value = null;
        String val = (String)redisTemplate.opsForValue().get(key);
        if (val == null || "".equals(val)){
            value = consumer1.getCache();
            redisTemplate.opsForValue().set(key,value,timeout, TimeUnit.SECONDS);
        }else {
            try {
                value = objectMapper.readValue(val,clazz);
            } catch (IOException e) {
                log.error("【获取单个缓存转换实体失败】, {}",e);
            }
        }
        return value;
    }

    /**
     * 获取集合缓存
     * @param key
     * @param clazz
     * @param consumer2
     * @param timeout
     * @param <T>
     * @return
     */
    public <T>List<T> getCache(String key,Class<T> clazz,Consumer2<T> consumer2,Long timeout){
        List<T> value = null;
        String val = (String)redisTemplate.opsForValue().get(key);
        if (val == null || "".equals(val)){
            value = consumer2.getCache();
            redisTemplate.opsForValue().set(key,value,timeout, TimeUnit.SECONDS);
        }else {
            try {
                JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, clazz);
                value = objectMapper.readValue(val,javaType);
            } catch (IOException e) {
                log.error("【获取集合缓存转换实体失败】, {}",e);
            }
        }
        return value;
    }

    /**
     * 单个缓存
     * @param <T>
     */
    @FunctionalInterface
    public interface Consumer1<T>{
        T getCache();
    }

    /**
     * 集合缓存
     * @param <T>
     */
    @FunctionalInterface
    public interface Consumer2<T>{
        List<T> getCache();
    }
}